racket lambda和let

lambda

(lambda kw-formals body ...+);kw-formals:参数,body:表达式
> ((lambda (x y) (+ x y)) 1 2);参数为x,y,表达式(+ x y),实参1,2
> 3

> (define add (lambda (x y) (+ x y)))
> (add 1 2)
3

> ((lambda (x [y 5]) (list y x)) 1 2);参数y有一个默认值5,若没有提供参数,则y输出5
'(2 1)

let location和top-level变量类似,location产生的时候使用一个从未使用过的名称,不能被重新生成和直接访问, 这里top-level变量应该指的是其它语言的全局变量。

(let ([id val-expr] ...) body ...+)
(let proc-id ([id init-expr] ...) body ...+)

从左到执行表达式,为每个id创建一个location,并将值赋给这个location,然后执行body中的语句。

> (let ([x 5] [y 5]) (+ x y));
10
> (let fac ([n 10])
    (if (zero? n)
        1
        (* n (fac (sub1 n)))))
3628800


(let* ([id val-expr] ...) body ...+)
和let相像,一个一个执行val-expr,为每个id创建location,绑定ids到val-exprS和bodyS中。
>(let* ([x 1]
       [y (+ x 1)])
   (list y x))
'(2 1)
如果此处将let*改为let,则会报错(x未定义,因为x为绑定到var-exprS中)



(letrec ([id val-expr] ...) body ...+)
和let相似,从左到右执行val-exprS,但所有idS的location是先创建的,当执行val-expr后,
idS马上被初始化,绑定到val-exprS和bodyS命名空间中。


(let-values ([(id ...) val-expr] ...) body ...+)
和let相似,val-expr中返回的变量必须和id中的数量一致,绑定到body中,

> (let-values ([(x y) (quotient/remainder 10 3)])
    (list y x))
'(1 3)
(let*-values ([(id ...) val-expr] ...) body ...+);和let-values相似,但会把location绑定到val-exprS中。

(letrec-values ([(id ...) val-expr] ...) body ...+);和letrec相似,对id赋值的方式不一样

Ref: 1.官方文档lambda 2.官方文档let